//
//  QRCodeViewController.swift
//  SinaBlog
//
//  Created by ChenWei on 15/10/8.
//  Copyright © 2015年 cw. All rights reserved.
//

import UIKit
import AVFoundation

class QRCodeViewController: UIViewController,UITabBarDelegate {
    
    /// 冲击波
    @IBOutlet weak var scanlingImageView: UIImageView!
    /// 底部tabBar
    @IBOutlet weak var customTabBar: UITabBar!
    /// qrCode顶部约束
    @IBOutlet weak var topConstraint: NSLayoutConstraint!
    /// 容器高度约束
    @IBOutlet weak var containerHeightConstraint: NSLayoutConstraint!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        customTabBar.selectedItem = customTabBar.items![0]
        customTabBar.delegate = self
       
    }
    
    override func viewDidAppear(animated: Bool) {
        super.viewDidAppear(animated)
        
        // 1.执行扫描动画
        startAnimator()
        
        // 2.开始二维码扫描
        startScanQRCode()
    }
    
    /// 返回首页
    @IBAction func close(sender: AnyObject) {
        dismissViewControllerAnimated(true, completion: nil)
    }
    
    /// 进入相册
    @IBAction func photoAlbum(sender: AnyObject) {
        print("进入相册")
    }
    
    
    // MARK:- 动画
    /// 开始扫描动画
    func startAnimator() {
        topConstraint.constant = -containerHeightConstraint.constant
        
        view.layoutIfNeeded()
        
        UIView.animateWithDuration(2.0) {[unowned self] () -> Void in
            UIView.setAnimationRepeatCount(MAXFLOAT)
            self.topConstraint.constant = self.containerHeightConstraint.constant
           self.view.layoutIfNeeded()
        }
    }
    
    // MARK - 二维码扫描
    /// 开始二维码扫描
    private func startScanQRCode() {
        // 1.判断是否可以添加输入设备
        if !session.canAddInput(inputDevice) {
            return
        }
        // 2.判断是否可以添加输出设备
        if !session.canAddOutput(output) {
            return
        }
        // 3.添加输入输出到会话中
        session.addInput(inputDevice)
        session.addOutput(output)
        // 4.设置输出数据解析类型
        // 必须添加输出对象到会话中设置才有效,否则报错
        output.metadataObjectTypes = output.availableMetadataObjectTypes
        // 5.设置输出代理,监听解析等到结果
        output.setMetadataObjectsDelegate(self, queue: dispatch_get_main_queue())
        // 6.添加预览图层
        view.layer.insertSublayer(previewLayer, atIndex: 0)
        previewLayer.addSublayer(drawLayer)
        // 7.利用会话开始扫描
        session.startRunning()
        
    }
    
    
    // MARK: -UITabBarDelegate
    func tabBar(tabBar: UITabBar, didSelectItem item: UITabBarItem) {

        
        containerHeightConstraint.constant = (item.tag == 1) ? 150 : 300
        topConstraint.constant = -containerHeightConstraint.constant
        scanlingImageView.layer.removeAllAnimations()
       
        startAnimator()
        
    }
    
    // MARK: - 懒加载
    /// 1.创建输入
    private lazy var inputDevice: AVCaptureDeviceInput? = {
        let device = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
        do{
            let input = try AVCaptureDeviceInput(device: device)
            return input;
        }catch{
            return nil
        }
    }()
    
    /// 2.创建输出
    private lazy var output: AVCaptureMetadataOutput = {
        let output = AVCaptureMetadataOutput()
        return output
    }()
    
    /// 3.创建会话
    private lazy var session: AVCaptureSession = {
        let session = AVCaptureSession()
        session.sessionPreset = AVCaptureSessionPreset1920x1080
        return session
    }()
    
    /// 4.创建预览图层
    private lazy var previewLayer: AVCaptureVideoPreviewLayer = {
        let layer = AVCaptureVideoPreviewLayer(session: self.session)
        layer.frame = UIScreen.mainScreen().bounds
        return layer
    }()
    
    /// 5.创建二维码扫描图层
    private lazy var drawLayer: CALayer = {
        let layer = CALayer()
        layer.frame = UIScreen.mainScreen().bounds
        return layer
    }()
   
}

extension QRCodeViewController: AVCaptureMetadataOutputObjectsDelegate {
    func captureOutput(captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [AnyObject]!, fromConnection connection: AVCaptureConnection!) {
        print("收到扫描数据")
        for objc in metadataObjects {
            // 1.将二维码转换的坐标转换成能够识别的坐标
            let codeObjc = previewLayer.transformedMetadataObjectForMetadataObject(objc as! AVMetadataObject)
            
            // 2. 根据转好的坐标绘制二维码描边
            drawCorners(codeObjc as! AVMetadataMachineReadableCodeObject)
            let metaDataObjc =  metadataObjects.last as! AVMetadataMachineReadableCodeObject
            let url = NSURL(string: metaDataObjc.stringValue)
            UIApplication.sharedApplication().openURL(url!)
            NSLog(message: metaDataObjc)
        }
    }
    
    /// 绘制二维码描边
    private func drawCorners(codeObjc: AVMetadataMachineReadableCodeObject) {
        // 0.移除以前的描边
        clearCorners()
        
        // 1.绘制路径
        let subLayer = CAShapeLayer()
        subLayer.lineWidth = 4
        subLayer.strokeColor = UIColor.redColor().CGColor
        subLayer.fillColor = UIColor.clearColor().CGColor
        
        // 2.从传入的对象中获取4个点,创建path
        let path = UIBezierPath()
        var point = CGPointZero
        var index = 0
        let dicArr = codeObjc.corners
        // 2.1取出第0个点
        // 将字典中的xy转换为CGPoint
        CGPointMakeWithDictionaryRepresentation((dicArr[index++] as! CFDictionary), &point)
        // 2.2移到到第0个点
        path.moveToPoint(point)
        // 2.3添加其它的点
        while index < dicArr.count {
            CGPointMakeWithDictionaryRepresentation((dicArr[index++] as! CFDictionary), &point)
            path.addLineToPoint(point)
        }
        
        // 2.4关闭路径
        path.closePath()
        
        //  2.5赋值给图层路径
        subLayer.path = path.CGPath
        
        // 3. 将layer添加到drawLayer上
        drawLayer.addSublayer(subLayer)
        
    }
    
    /// 移除以前的描边
    private func clearCorners() {
        if drawLayer.sublayers == nil || drawLayer.sublayers?.count == 0 {
            return
        }
        
        for subLayer in drawLayer.sublayers! {
            subLayer.removeFromSuperlayer()
        }
    }
}
